/*
 * StringShim.cpp
 *
 *  Created on: 2011-4-10
 *      Author: terry
 */

#include "StringShim.h"
#include <string.h>
#include <windows.h>

StringShim::StringShim() :
	m_ansiText(0),
	m_wideText(0),
	m_ansiBuffer(0),
	m_wideBuffer(0)
{
}

StringShim::~StringShim()
{
	cleanup();
}

StringShim::StringShim(const char* ansiText) :
	m_ansiText(ansiText),
	m_wideText(0),
	m_ansiBuffer(0),
	m_wideBuffer(0)
{

}

StringShim::StringShim(const wchar_t* wideText):
	m_ansiText(0),
	m_wideText(wideText),
	m_ansiBuffer(0),
	m_wideBuffer(0)
{

}

StringShim::StringShim(const std::string& ansiText) :
	m_ansiText(ansiText.c_str()),
	m_wideText(0),
	m_ansiBuffer(0),
	m_wideBuffer(0)
{

}

StringShim::StringShim(const std::wstring& wideText) :
	m_ansiText(),
	m_wideText(wideText.c_str()),
	m_ansiBuffer(0),
	m_wideBuffer(0)
{

}


const wchar_t* StringShim::toUnicode()
{
	if (m_wideText)
	{
		return m_wideText;
	}

	if (m_ansiText)
	{
		// convert ansi to unicode
		int length = strlen(m_ansiText);
		int unicodeLen = MultiByteToWideChar(CP_ACP, 0, m_ansiText, (int)length, NULL, 0);
		m_wideBuffer = new wchar_t[unicodeLen + 1];
        memset(m_wideBuffer, 0, (unicodeLen + 1) * sizeof(wchar_t));
		unicodeLen = MultiByteToWideChar(CP_ACP, 0, m_ansiText, (int)length, m_wideBuffer, unicodeLen);

		m_wideText = m_wideBuffer;
	}

	return m_wideText;
}

const char* StringShim::toAnsi()
{
	if (m_ansiText)
	{
		return m_ansiText;
	}

	if (m_wideText)
	{
		// convert unicode to ansi
		int unicodeLen = wcslen(m_wideText);
		int length = WideCharToMultiByte(CP_ACP, 0, m_wideText, unicodeLen, NULL, 0, NULL, NULL);
		m_ansiBuffer = new char[length + 1];
        memset(m_ansiBuffer, 0, length + 1);
		WideCharToMultiByte(CP_ACP, 0, m_wideText, unicodeLen, m_ansiBuffer, length, NULL, NULL);

		m_ansiText = m_ansiBuffer;
	}
	return m_ansiText;
}

StringShim::operator const wchar_t* ()
{
	return toUnicode();
}

StringShim::operator const char* ()
{
	return toAnsi();
}

void StringShim::cleanup()
{
	if (m_ansiBuffer)
	{
		delete[] m_ansiBuffer;
		m_ansiBuffer = NULL;
	}

	if (m_wideBuffer)
	{
		delete[] m_wideBuffer;
		m_wideBuffer = NULL;
	}
}


size_t StringShim::copyTo(char* buffer, size_t length)
{
	if (!buffer)
	{
		return 0;
	}
	if (length == 0)
	{
		return 0;
	}

	const char* str = toAnsi();
	size_t srcLength = strlen(str);
	if (length > srcLength)
	{
		length = srcLength;
	}
	strncpy_s(buffer, length, str, length);
	return length;
}